/*
 * write_cc.c
 *
 *  Created on: 2012/08/01
 *      Author: owner
 */

#include <stdio.h>
#include "sqlite3.h"
#include "db_def.h"
#include "core.h"
#include "core_internal.h"
#include "Id.h"
#include "../../CCore/table/table.h"
#include "../../CCore/parser/cc/cc.h"
#include "../../CCore/table/core_table.h"
#include "../../CCore/parser/coredef.h"

/*TBL_DECLARATION*/
static INT insertDeclaration(sqlite3 *db, AST tuIdx) {
	INT rc = 0;
	sqlite3_stmt * stmt;
	const char *zTail;
	PSZ sql_insert = NULL;
	BOOL bIsErr = FALSE;

	AST max = 0;
	AST i = 0;

	rc = sqlite3_exec(db, "begin;", 0, 0, 0);
	if (rc != SQLITE_OK) {
		return rc;
	}

	max = stDeclarationAccess.getMax();

	sql_insert = sqlite3_mprintf("INSERT INTO %q VALUES(?,?,?,?,?,?,?,?,?,?);",
			TBL_DECLARATION);
	rc = sqlite3_prepare(db, sql_insert, -1, &stmt, &zTail);
	if (rc != SQLITE_OK || stmt == NULL ) {
		if (sql_insert != NULL ) {
			sqlite3_free(sql_insert);
		}
		if (stmt != NULL ) {
			sqlite3_finalize(stmt);
		}
		return COEXIT_ERROR;
	}

	for (i = 1; i <= max; i++) {

		sqlite3_bind_int(stmt, CC_UNIT_INDEX, tuIdx);
		sqlite3_bind_int(stmt, CC_TABLE_INDEX, i);

		sqlite3_bind_int(stmt, DECL_TYPE_SPECIFIER_INFO,
				stDeclarationAccess.typeSpecifier.get(i));

		sqlite3_bind_int(stmt, DECL_DECLARATOR_INFO,
				stDeclarationAccess.declarator.get(i));

		sqlite3_bind_int(stmt, DECL_CODE_SCOPE_INFO,
				stDeclarationAccess.codeScp.get(i));

		sqlite3_bind_int(stmt, DECL_PARENT_KIND,
				stDeclarationAccess.parentKind.get(i));

		sqlite3_bind_int(stmt, DECL_NAMESPACE_KIND,
				stDeclarationAccess.namespace.get(i));

		sqlite3_bind_int(stmt, DECL_PARENT_INDEX,
				stDeclarationAccess.parentIdx.get(i));

		sqlite3_bind_int(stmt, DECL_TRANSUNIT_INFO,
				stDeclarationAccess.translationUnit.get(i));

		sqlite3_bind_int(stmt, DECL_NEXT_DECLARATION_INFO,
				stDeclarationAccess.next.get(i));

		rc = sqlite3_step(stmt);
		if (rc != SQLITE_DONE) {
			bIsErr = TRUE;
			printf("%s", sqlite3_errmsg(db));
			break;
		}
		sqlite3_reset(stmt);
	}

	if (bIsErr) {
		rc = sqlite3_exec(db, "rollback;", 0, 0, 0);
	} else {
		rc = sqlite3_exec(db, "commit;", 0, 0, 0);
	}

	if (sql_insert != NULL ) {
		sqlite3_free(sql_insert);
	}
	if (stmt != NULL ) {
		rc = sqlite3_finalize(stmt);
	}
	return rc;
}

/*TBL_DECLARATOR*/
static INT insertDeclarator(sqlite3 *db, AST tuIdx) {
	INT rc = 0;
	sqlite3_stmt * stmt;
	const char *zTail;
	PSZ sql_insert = NULL;
	BOOL bIsErr = FALSE;

	AST max = 0;
	AST i = 0;
	U2 declaratorKind = 0;

	rc = sqlite3_exec(db, "begin;", 0, 0, 0);
	if (rc != SQLITE_OK) {
		return rc;
	}

	max = stDeclaratorAccess.getMax();

	sql_insert = sqlite3_mprintf(
			"INSERT INTO %q VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?);",
			TBL_DECLARATOR);
	rc = sqlite3_prepare(db, sql_insert, -1, &stmt, &zTail);
	if (rc != SQLITE_OK || stmt == NULL ) {
		if (sql_insert != NULL ) {
			sqlite3_free(sql_insert);
		}
		if (stmt != NULL ) {
			sqlite3_finalize(stmt);
		}
		return COEXIT_ERROR;
	}

	for (i = 1; i <= max; i++) {

		sqlite3_bind_int(stmt, CC_UNIT_INDEX, tuIdx);
		sqlite3_bind_int(stmt, CC_TABLE_INDEX, i);

		sqlite3_bind_int(stmt, DECLARATOR_NEXT_DECLARATOR_INFO,
				stDeclaratorAccess.nextDeclarator.get(i));

		sqlite3_bind_int(stmt, DECLARATOR_PARENT_DECLARATOR_INFO,
				stDeclaratorAccess.parentDeclarator.get(i));

		sqlite3_bind_int(stmt, DECLARATOR_DECLARATION_INFO,
				stDeclaratorAccess.declaration.get(i));

		declaratorKind = stDeclaratorAccess.declaratorKind.get(i);
		sqlite3_bind_int(stmt, DECLARATOR_DECLARATOR_KIND, declaratorKind);

		sqlite3_bind_int(stmt, DECLARATOR_X_TBL_INFO, 0);
		sqlite3_bind_int(stmt, DECLARATOR_POINTER_VOLATILE_NUMBER, 0);
		sqlite3_bind_int(stmt, DECLARATOR_POINTER_CONST_NUMBER, 0);
		sqlite3_bind_int(stmt, DECLARATOR_POINTER_RESTRICT_NUMBER, 0);
		switch (declaratorKind) {
		case DECLARATOR_BITFIELD:
			sqlite3_bind_int(stmt, DECLARATOR_X_TBL_INFO,
					stDeclaratorAccess.bitIdx.get(i));
			break;

		case DECLARATOR_ARRAY:
			sqlite3_bind_int(stmt, DECLARATOR_X_TBL_INFO,
					stDeclaratorAccess.arrayIdx.get(i));
			break;

		case DECLARATOR_FUNC:
			sqlite3_bind_int(stmt, DECLARATOR_X_TBL_INFO,
					stDeclaratorAccess.paramChain.get(i));
			break;

		case DECLARATOR_INIT:
			sqlite3_bind_int(stmt, DECLARATOR_X_TBL_INFO,
					stDeclaratorAccess.initialExpList.get(i));
			break;

		case DECLARATOR_SYM:
			sqlite3_bind_int(stmt, DECLARATOR_X_TBL_INFO,
					stDeclaratorAccess.symbol.get(i));
			break;

		case DECLARATOR_POINTER:
			sqlite3_bind_int(stmt, DECLARATOR_POINTER_VOLATILE_NUMBER,
					stDeclaratorAccess.volatileNum.get(i));
			sqlite3_bind_int(stmt, DECLARATOR_POINTER_CONST_NUMBER,
					stDeclaratorAccess.constNum.get(i));
			sqlite3_bind_int(stmt, DECLARATOR_POINTER_RESTRICT_NUMBER,
					stDeclaratorAccess.restrictNum.get(i));
			break;

		default:
			break;
		}

		sqlite3_bind_int(stmt, DECLARATOR_CHILD_DECLARATOR_INFO,
				stDeclaratorAccess.childDeclarator.get(i));

		sqlite3_bind_int(stmt, DECLARATOR_TYPE_INFO,
				stDeclaratorAccess.type.get(i));

		sqlite3_bind_int(stmt, DECLARATOR_CODE_SCOPE_INFO,
				stDeclaratorAccess.codeScp.get(i));

		rc = sqlite3_step(stmt);
		if (rc != SQLITE_DONE) {
			bIsErr = TRUE;
			printf("%s", sqlite3_errmsg(db));
			break;
		}
		sqlite3_reset(stmt);
	}

	if (bIsErr) {
		rc = sqlite3_exec(db, "rollback;", 0, 0, 0);
	} else {
		rc = sqlite3_exec(db, "commit;", 0, 0, 0);
	}

	if (sql_insert != NULL ) {
		sqlite3_free(sql_insert);
	}
	if (stmt != NULL ) {
		rc = sqlite3_finalize(stmt);
	}
	return rc;
}

/*TBL_TYPESPECIFIER*/
static INT insertTypeSpecifier(sqlite3 *db, AST tuIdx) {
	INT rc = 0;
	sqlite3_stmt * stmt;
	const char *zTail;
	PSZ sql_insert = NULL;
	BOOL bIsErr = FALSE;

	AST max = 0;
	AST i = 0;
	U2 specifyKind = 0;

	rc = sqlite3_exec(db, "begin;", 0, 0, 0);
	if (rc != SQLITE_OK) {
		return rc;
	}

	max = stTypeSpecifierAccess.getMax();

	sql_insert =
			sqlite3_mprintf(
					"INSERT INTO %q VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);",
					TBL_TYPESPECIFIER);
	rc = sqlite3_prepare(db, sql_insert, -1, &stmt, &zTail);
	if (rc != SQLITE_OK || stmt == NULL ) {
		if (sql_insert != NULL ) {
			sqlite3_free(sql_insert);
		}
		if (stmt != NULL ) {
			sqlite3_finalize(stmt);
		}
		return COEXIT_ERROR;
	}

	for (i = 1; i <= max; i++) {

		sqlite3_bind_int(stmt, CC_UNIT_INDEX, tuIdx);
		sqlite3_bind_int(stmt, CC_TABLE_INDEX, i);

		sqlite3_bind_int(stmt, SPECIFIER_CODE_SCOPE_INFO,
				stTypeSpecifierAccess.codeScp.get(i));

		sqlite3_bind_int(stmt, SPECIFIER_DECLARATION_INFO,
				stTypeSpecifierAccess.declaration.get(i));

		sqlite3_bind_int(stmt, SPECIFIER_RESTRICT_NUMBER,
				stTypeSpecifierAccess.restrictNum.get(i));

		sqlite3_bind_int(stmt, SPECIFIER_VOLATILE_NUMBER,
				stTypeSpecifierAccess.volatileNum.get(i));

		sqlite3_bind_int(stmt, SPECIFIER_CONST_NUMBER,
				stTypeSpecifierAccess.constNum.get(i));

		sqlite3_bind_int(stmt, SPECIFIER_EXTERN_NUMBER,
				stTypeSpecifierAccess.externNum.get(i));

		sqlite3_bind_int(stmt, SPECIFIER_STATIC_NUMBER,
				stTypeSpecifierAccess.staticNum.get(i));

		sqlite3_bind_int(stmt, SPECIFIER_AUTO_NUMBER,
				stTypeSpecifierAccess.autoNum.get(i));

		sqlite3_bind_int(stmt, SPECIFIER_TYPEDEF_NUMBER,
				stTypeSpecifierAccess.typedefNum.get(i));

		sqlite3_bind_int(stmt, SPECIFIER_REGISTER_NUMBER,
				stTypeSpecifierAccess.registerNum.get(i));

		sqlite3_bind_int(stmt, SPECIFIER_INTERRUPT_NUMBER,
				stTypeSpecifierAccess.interruptNum.get(i));

		sqlite3_bind_int(stmt, SPECIFIER_INLINE_NUMBER,
				stTypeSpecifierAccess.inlineNum.get(i));

		sqlite3_bind_int(stmt, SPECIFIER_ASM_NUMBER,
				stTypeSpecifierAccess.asmNum.get(i));

		sqlite3_bind_int(stmt, SPECIFIER_NEAR_NUMBER,
				stTypeSpecifierAccess.nearNum.get(i));

		sqlite3_bind_int(stmt, SPECIFIER_FAR_NUMBER,
				stTypeSpecifierAccess.farNum.get(i));

		specifyKind = stTypeSpecifierAccess.specifyKind.get(i);
		sqlite3_bind_int(stmt, SPECIFIER_SPECIFIER_KIND, specifyKind);

		sqlite3_bind_int(stmt, SPECIFIER_SIGNED_NUMBER, 0);
		sqlite3_bind_int(stmt, SPECIFIER_UNSIGNED_NUMBER, 0);
		sqlite3_bind_int(stmt, SPECIFIER_LONG_NUMBER, 0);
		sqlite3_bind_int(stmt, SPECIFIER_SHORT_NUMBER, 0);
		sqlite3_bind_int(stmt, SPECIFIER_MEMBER_CHAIN_INFO, 0);
		if (specifyKind == TYPEDEF_BASE) {
			sqlite3_bind_int(stmt, SPECIFIER_SIGNED_NUMBER,
					stTypeSpecifierAccess.signNum.get(i));

			sqlite3_bind_int(stmt, SPECIFIER_UNSIGNED_NUMBER,
					stTypeSpecifierAccess.unsigneNum.get(i));

			sqlite3_bind_int(stmt, SPECIFIER_LONG_NUMBER,
					stTypeSpecifierAccess.longNum.get(i));

			sqlite3_bind_int(stmt, SPECIFIER_SHORT_NUMBER,
					stTypeSpecifierAccess.shortNum.get(i));
		} else if (specifyKind == TYPEDEF_UNION || specifyKind == TYPEDEF_STRUCT
				|| specifyKind == TYPEDEF_ENUM) {
			sqlite3_bind_int(stmt, SPECIFIER_MEMBER_CHAIN_INFO,
					stTypeSpecifierAccess.memberChain.get(i));
		}

		sqlite3_bind_int(stmt, SPECIFIER_SYMBOL_INFO,
				stTypeSpecifierAccess.symbol.get(i));

		sqlite3_bind_int(stmt, SPECIFIER_TYPE_INFO,
				stTypeSpecifierAccess.typeinfo.get(i));

		rc = sqlite3_step(stmt);
		if (rc != SQLITE_DONE) {
			bIsErr = TRUE;
			printf("%s", sqlite3_errmsg(db));
			break;
		}
		sqlite3_reset(stmt);
	}

	if (bIsErr) {
		rc = sqlite3_exec(db, "rollback;", 0, 0, 0);
	} else {
		rc = sqlite3_exec(db, "commit;", 0, 0, 0);
	}

	if (sql_insert != NULL ) {
		sqlite3_free(sql_insert);
	}
	if (stmt != NULL ) {
		rc = sqlite3_finalize(stmt);
	}
	return rc;
}

/*TBL_EXPRESSION*/
static INT insertExpression(sqlite3 *db, AST tuIdx) {
	INT rc = 0;
	sqlite3_stmt * stmt;
	const char *zTail;
	PSZ sql_insert = NULL;
	BOOL bIsErr = FALSE;

	AST max = 0;
	AST i = 0;
	U4 opKind = 0;
	U2 parentKind = 0;

	rc = sqlite3_exec(db, "begin;", 0, 0, 0);
	if (rc != SQLITE_OK) {
		return rc;
	}

	max = stExpressionAccess.getMax();

	sql_insert = sqlite3_mprintf(
			"INSERT INTO %q VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);",
			TBL_EXPRESSION);
	rc = sqlite3_prepare(db, sql_insert, -1, &stmt, &zTail);
	if (rc != SQLITE_OK || stmt == NULL ) {
		if (sql_insert != NULL ) {
			sqlite3_free(sql_insert);
		}
		if (stmt != NULL ) {
			sqlite3_finalize(stmt);
		}
		return COEXIT_ERROR;
	}

	for (i = 1; i <= max; i++) {

		sqlite3_bind_int(stmt, CC_UNIT_INDEX, tuIdx);
		sqlite3_bind_int(stmt, CC_TABLE_INDEX, i);

		opKind = stExpressionAccess.opKind.get(i);
		sqlite3_bind_int(stmt, EXP_OP_KIND, opKind);

		switch (opKind) {
		case EXPR_CONSTANT:
			sqlite3_bind_int(stmt, EXP_PRIMARY_X_INFO,
					stExpressionAccess.result_value.get(i));
			break;

		case EXPR_STRING:
			sqlite3_bind_int(stmt, EXP_PRIMARY_X_INFO,
					stExpressionAccess.result_constStr.get(i));
			break;

		case EXPR_DECLARATION:
			sqlite3_bind_int(stmt, EXP_PRIMARY_X_INFO,
					stExpressionAccess.result_declaration.get(i));
			break;

		case EXPR_IDENTIFIER:
			sqlite3_bind_int(stmt, EXP_PRIMARY_X_INFO,
					stExpressionAccess.result_symbol.get(i));
			break;

		case EXPR_TOKEN:
			sqlite3_bind_int(stmt, EXP_PRIMARY_X_INFO,
					stExpressionAccess.result_temp_token.get(i));
			break;

		case EXPR_STATEMENT:
			sqlite3_bind_int(stmt, EXP_PRIMARY_X_INFO,
					stExpressionAccess.result_statement.get(i));
			break;

		case EXPR_INITEXPRLIST:
			sqlite3_bind_int(stmt, EXP_PRIMARY_X_INFO,
					stExpressionAccess.result_exprlist.get(i));
			break;

		default:
			sqlite3_bind_int(stmt, EXP_PRIMARY_X_INFO, 0);
			break;
		}

		sqlite3_bind_int(stmt, EXP_TYPE_INFO, stExpressionAccess.type.get(i));

		sqlite3_bind_int(stmt, EXP_CASTED_TYPE_INFO,
				stExpressionAccess.castedType.get(i));

		sqlite3_bind_int(stmt, EXP_CALCUTE_VALUE_INFO,
				stExpressionAccess.constValue.get(i));

		sqlite3_bind_int(stmt, EXP_CODE_SCOPE_INFO,
				stExpressionAccess.codeScp.get(i));

		sqlite3_bind_int(stmt, EXP_IS_ILLEGAL_EXP,
				stExpressionAccess.bIllegal.get(i));

		sqlite3_bind_int(stmt, EXP_IS_L_VALUE,
				stExpressionAccess.blValue.get(i));

		sqlite3_bind_int(stmt, EXP_IS_MODIFIABLE,
				stExpressionAccess.bModifiabe.get(i));

		sqlite3_bind_int(stmt, EXP_CONST_FLAG,
				stExpressionAccess.constFlg.get(i));

		parentKind = stExpressionAccess.parentKind.get(i);
		sqlite3_bind_int(stmt, EXP_PARENT_KIND, parentKind);

		switch (parentKind) {
		case KIND_STATEMENTINFO:
			sqlite3_bind_int(stmt, EXP_PARENT_TABLE_INFO,
					stExpressionAccess.parent_statement.get(i));
			break;

		case KIND_EXPRESSIONINFO:
			sqlite3_bind_int(stmt, EXP_PARENT_TABLE_INFO,
					stExpressionAccess.parent_expression.get(i));
			break;

		case KIND_INITIALEXPLIST:
			sqlite3_bind_int(stmt, EXP_PARENT_TABLE_INFO,
					stExpressionAccess.parent_explist.get(i));
			break;

		case KIND_DECLARATOR:
			sqlite3_bind_int(stmt, EXP_PARENT_TABLE_INFO,
					stExpressionAccess.parent_declarator.get(i));
			break;

		case KIND_INITDESIGNATION:
			sqlite3_bind_int(stmt, EXP_PARENT_TABLE_INFO,
					stExpressionAccess.parent_designation.get(i));
			break;

		default:
			sqlite3_bind_int(stmt, EXP_PARENT_TABLE_INFO, 0);
			break;
		}

		sqlite3_bind_int(stmt, EXP_LEFT_NODE_EXP_INFO,
				stExpressionAccess.leftChild.get(i));

		sqlite3_bind_int(stmt, EXP_RIGHT_NODE_EXP_INFO,
				stExpressionAccess.rightChild.get(i));

		rc = sqlite3_step(stmt);
		if (rc != SQLITE_DONE) {
			bIsErr = TRUE;
			printf("%s", sqlite3_errmsg(db));
			break;
		}
		sqlite3_reset(stmt);
	}

	if (bIsErr) {
		rc = sqlite3_exec(db, "rollback;", 0, 0, 0);
	} else {
		rc = sqlite3_exec(db, "commit;", 0, 0, 0);
	}

	if (sql_insert != NULL ) {
		sqlite3_free(sql_insert);
	}
	if (stmt != NULL ) {
		rc = sqlite3_finalize(stmt);
	}
	return rc;
}

/*TBL_EXPRESSIONLIST*/
static INT insertExpressionList(sqlite3 *db, AST tuIdx) {
	INT rc = 0;
	sqlite3_stmt * stmt;
	const char *zTail;
	PSZ sql_insert = NULL;
	BOOL bIsErr = FALSE;

	AST max = 0;
	AST i = 0;
	U2 paramKind = 0;

	rc = sqlite3_exec(db, "begin;", 0, 0, 0);
	if (rc != SQLITE_OK) {
		return rc;
	}

	max = stExpressionListAccess.getMax();

	sql_insert = sqlite3_mprintf(
			"INSERT INTO %q VALUES(?,?,?,?,?,?,?,?,?,?,?);",
			TBL_EXPRESSIONLIST);
	rc = sqlite3_prepare(db, sql_insert, -1, &stmt, &zTail);
	if (rc != SQLITE_OK || stmt == NULL ) {
		if (sql_insert != NULL ) {
			sqlite3_free(sql_insert);
		}
		if (stmt != NULL ) {
			sqlite3_finalize(stmt);
		}
		return COEXIT_ERROR;
	}

	for (i = 1; i <= max; i++) {

		sqlite3_bind_int(stmt, CC_UNIT_INDEX, tuIdx);
		sqlite3_bind_int(stmt, CC_TABLE_INDEX, i);

		sqlite3_bind_int(stmt, EXPLIST_IS_ILLEGAL,
				stExpressionListAccess.bIllegal.get(i));

		sqlite3_bind_int(stmt, EXPLIST_CONST_FLAG,
				stExpressionListAccess.constFlg.get(i));

		sqlite3_bind_int(stmt, EXPLIST_PARENT_KIND,
				stExpressionListAccess.parentKind.get(i));

		paramKind = stExpressionListAccess.parameterKind.get(i);
		sqlite3_bind_int(stmt, EXPLIST_PARAM_KIND, paramKind);

		switch (paramKind) {
		case KIND_INITIALEXPLIST:
			sqlite3_bind_int(stmt, EXPLIST_EXP_X_INFO,
					stExpressionListAccess.expressionList.get(i));
			break;
		case KIND_EXPRESSIONINFO:
			sqlite3_bind_int(stmt, EXPLIST_EXP_X_INFO,
					stExpressionListAccess.expression.get(i));
			break;
		default:
			sqlite3_bind_int(stmt, EXPLIST_EXP_X_INFO, 0);
			break;
		}

		sqlite3_bind_int(stmt, EXPLIST_NEXT_EXP_LIST_INFO,
				stExpressionListAccess.next.get(i));

		sqlite3_bind_int(stmt, EXPLIST_PARENT_INFO,
				stExpressionListAccess.parent.get(i));

		sqlite3_bind_int(stmt, EXPLIST_CODE_SCOPE_INFO,
				stExpressionListAccess.codeScp.get(i));

		sqlite3_bind_int(stmt, EXPLIST_DESIGNATION_INFO,
				stExpressionListAccess.designation.get(i));

		rc = sqlite3_step(stmt);
		if (rc != SQLITE_DONE) {
			bIsErr = TRUE;
			printf("%s", sqlite3_errmsg(db));
			break;
		}
		sqlite3_reset(stmt);
	}

	if (bIsErr) {
		rc = sqlite3_exec(db, "rollback;", 0, 0, 0);
	} else {
		rc = sqlite3_exec(db, "commit;", 0, 0, 0);
	}

	if (sql_insert != NULL ) {
		sqlite3_free(sql_insert);
	}
	if (stmt != NULL ) {
		rc = sqlite3_finalize(stmt);
	}
	return rc;
}

/*TBL_INITIALIZERDESIGNATION*/
static INT insertInitializerDesignation(sqlite3 *db, AST tuIdx) {
	INT rc = 0;
	sqlite3_stmt * stmt;
	const char *zTail;
	PSZ sql_insert = NULL;
	BOOL bIsErr = FALSE;

	AST max = 0;
	AST i = 0;
	U2 kind = 0;

	rc = sqlite3_exec(db, "begin;", 0, 0, 0);
	if (rc != SQLITE_OK) {
		return rc;
	}

	max = stInitDesignationAccess.getMax();

	sql_insert = sqlite3_mprintf("INSERT INTO %q VALUES(?,?,?,?,?,?,?,?,?);",
			TBL_INITIALIZERDESIGNATION);
	rc = sqlite3_prepare(db, sql_insert, -1, &stmt, &zTail);
	if (rc != SQLITE_OK || stmt == NULL ) {
		if (sql_insert != NULL ) {
			sqlite3_free(sql_insert);
		}
		if (stmt != NULL ) {
			sqlite3_finalize(stmt);
		}
		return COEXIT_ERROR;
	}

	for (i = 1; i <= max; i++) {

		sqlite3_bind_int(stmt, CC_UNIT_INDEX, tuIdx);
		sqlite3_bind_int(stmt, CC_TABLE_INDEX, i);

		kind = stInitDesignationAccess.kind.get(i);
		sqlite3_bind_int(stmt, INIT_DESIGNATION_KIND, kind);

		sqlite3_bind_int(stmt, INIT_IS_ILLEGAL,
				stInitDesignationAccess.bIllegal.get(i));

		switch (kind) {
		case DESIGNATION_ARRAY:
			sqlite3_bind_int(stmt, INIT_X_INFO,
					stInitDesignationAccess.const_expression.get(i));
			break;
		case DESIGNATION_MEMBER:
			sqlite3_bind_int(stmt, INIT_X_INFO,
					stInitDesignationAccess.identifier.get(i));
			break;
		case DESIGNATION_TOKEN:
			sqlite3_bind_int(stmt, INIT_X_INFO,
					stInitDesignationAccess.token.get(i));
			break;
		default:
			sqlite3_bind_int(stmt, INIT_X_INFO, 0);
			break;
		}

		sqlite3_bind_int(stmt, INIT_PARENT_INFO,
				stInitDesignationAccess.parent.get(i));

		sqlite3_bind_int(stmt, INIT_CHILD_INFO,
				stInitDesignationAccess.child.get(i));

		sqlite3_bind_int(stmt, INIT_CODE_SCOPE_INFO,
				stInitDesignationAccess.codeScp.get(i));

		sqlite3_bind_int(stmt, INIT_EXP_LIST_INFO,
				stInitDesignationAccess.initializer.get(i));

		rc = sqlite3_step(stmt);
		if (rc != SQLITE_DONE) {
			bIsErr = TRUE;
			printf("%s", sqlite3_errmsg(db));
			break;
		}
		sqlite3_reset(stmt);
	}

	if (bIsErr) {
		rc = sqlite3_exec(db, "rollback;", 0, 0, 0);
	} else {
		rc = sqlite3_exec(db, "commit;", 0, 0, 0);
	}

	if (sql_insert != NULL ) {
		sqlite3_free(sql_insert);
	}
	if (stmt != NULL ) {
		rc = sqlite3_finalize(stmt);
	}
	return rc;
}

/*TBL_STATEMENT*/
static INT insertStatement(sqlite3 *db, AST tuIdx) {
	INT rc = 0;
	sqlite3_stmt * stmt;
	const char *zTail;
	PSZ sql_insert = NULL;
	BOOL bIsErr = FALSE;

	AST max = 0;
	AST i = 0;
	U2 stmtKind = 0;
	U2 parentKind = 0;

	rc = sqlite3_exec(db, "begin;", 0, 0, 0);
	if (rc != SQLITE_OK) {
		return rc;
	}

	max = stStatementAccess.getMax();

	sql_insert = sqlite3_mprintf(
			"INSERT INTO %q VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);",
			TBL_STATEMENT);
	rc = sqlite3_prepare(db, sql_insert, -1, &stmt, &zTail);
	if (rc != SQLITE_OK || stmt == NULL ) {
		if (sql_insert != NULL ) {
			sqlite3_free(sql_insert);
		}
		if (stmt != NULL ) {
			sqlite3_finalize(stmt);
		}
		return COEXIT_ERROR;
	}

	for (i = 1; i <= max; i++) {

		sqlite3_bind_int(stmt, CC_UNIT_INDEX, tuIdx);
		sqlite3_bind_int(stmt, CC_TABLE_INDEX, i);

		stmtKind = stStatementAccess.statmentKind.get(i);
		sqlite3_bind_int(stmt, STMT_STATEMENT_KIND, stmtKind);

		sqlite3_bind_int(stmt, STMT_TABLE_INFO_0, 0);
		sqlite3_bind_int(stmt, STMT_TABLE_INFO_1, 0);
		sqlite3_bind_int(stmt, STMT_TABLE_INFO_2, 0);
		sqlite3_bind_int(stmt, STMT_TABLE_INFO_3, 0);
		sqlite3_bind_int(stmt, STMT_TABLE_INFO_4, 0);
		switch (stmtKind) {
		case STMT_DEC:
			sqlite3_bind_int(stmt, STMT_DECLARATION,
					stStatementAccess.dec_declaration.get(i));
			break;
		case STMT_FOR:
			sqlite3_bind_int(stmt, STMT_FOR_INIT_DECLARATION_INFO,
					stStatementAccess.for_Init_Decl.get(i));
			sqlite3_bind_int(stmt, STMT_FOR_INIT_EXP_INFO,
					stStatementAccess.for_initExp.get(i));
			sqlite3_bind_int(stmt, STMT_FOR_COND_EXP_INFO,
					stStatementAccess.for_CondExp.get(i));
			sqlite3_bind_int(stmt, STMT_FOR_INC_EXP_INFO,
					stStatementAccess.for_IncExp.get(i));
			sqlite3_bind_int(stmt, STMT_FOR_BODY_STATEMENT_INFO,
					stStatementAccess.for_Body.get(i));
			break;
		case STMT_LABEL:
			sqlite3_bind_int(stmt, STMT_LABEL_SYMBOL_INFO,
					stStatementAccess.label_name.get(i));
			sqlite3_bind_int(stmt, STMT_LABEL_STATEMENT_INFO,
					stStatementAccess.label_statement.get(i));
			sqlite3_bind_int(stmt, STMT_LABEL_GOTO_CHAIN_INFO,
					stStatementAccess.label_gotoChain.get(i));
			break;
		case STMT_CASE:
			sqlite3_bind_int(stmt, STMT_CASE_SWITCH_STMT_INFO,
					stStatementAccess.case_switch.get(i));
			sqlite3_bind_int(stmt, STMT_CASE_CONST_EXP_INFO,
					stStatementAccess.case_constExp.get(i));
			sqlite3_bind_int(stmt, STMT_CASE_CHILD_STMT_INFO,
					stStatementAccess.case_statement.get(i));
			sqlite3_bind_int(stmt, STMT_CASE_NEXT_CASE_INFO,
					stStatementAccess.case_nextCase.get(i));
			break;
		case STMT_DEFAULT:
			sqlite3_bind_int(stmt, STMT_DEFAULT_SWITCH_STMT_INFO,
					stStatementAccess.default_switch.get(i));
			sqlite3_bind_int(stmt, STMT_DEFAULT_CHILD_STMT_INFO,
					stStatementAccess.default_statement.get(i));
			break;
		case STMT_BLOCK:
			sqlite3_bind_int(stmt, STMT_BLOCK_CHAIN_INFO,
					stStatementAccess.block_stmtlist.get(i));
			break;
		case STMT_EXP:
			sqlite3_bind_int(stmt, STMT_EXP_STMT_EXP_INFO,
					stStatementAccess.exp_exp.get(i));
			break;
		case STMT_IF:
			sqlite3_bind_int(stmt, STMT_IF_COND_EXP_INFO,
					stStatementAccess.if_condExp.get(i));
			sqlite3_bind_int(stmt, STMT_IF_BODY_STMT_INFO,
					stStatementAccess.if_body.get(i));
			sqlite3_bind_int(stmt, STMT_IF_ELSE_BODY_STMT_INFO,
					stStatementAccess.if_else_body.get(i));
			break;
		case STMT_SWITCH:
			sqlite3_bind_int(stmt, STMT_SWITCH_COND_INFO,
					stStatementAccess.switch_condExp.get(i));
			sqlite3_bind_int(stmt, STMT_SWITCH_BODY_STMT_INFO,
					stStatementAccess.switch_body.get(i));
			sqlite3_bind_int(stmt, STMT_SWITCH_FIRST_CASE_STMT_INFO,
					stStatementAccess.switch_firstCase.get(i));
			sqlite3_bind_int(stmt, STMT_SWITCH_DEFAULT_STMT_INFO,
					stStatementAccess.switch_default.get(i));
			break;
		case STMT_WHILE:
			sqlite3_bind_int(stmt, STMT_WHILE_COND_EXP_INFO,
					stStatementAccess.while_condExp.get(i));
			sqlite3_bind_int(stmt, STMT_WHILE_BODY_STMT_INFO,
					stStatementAccess.while_body.get(i));
			break;
		case STMT_DO:
			sqlite3_bind_int(stmt, STMT_DO_BODY_STMT_INFO,
					stStatementAccess.do_body.get(i));
			sqlite3_bind_int(stmt, STMT_DO_COND_EXP_INFO,
					stStatementAccess.do_condExp.get(i));
			break;
		case STMT_GOTO:
			sqlite3_bind_int(stmt, STMT_GOTO_LABEL_SYMBOL_INFO,
					stStatementAccess.goto_sym.get(i));
			sqlite3_bind_int(stmt, STMT_GOTO_LABEL_STMT_INFO,
					stStatementAccess.goto_statement.get(i));
			break;
		case STMT_CONTINUE:
			sqlite3_bind_int(stmt, STMT_CONTINUE_LOOP_STMT_INFO,
					stStatementAccess.continue_statement.get(i));
			break;
		case STMT_BREAK:
			sqlite3_bind_int(stmt, STMT_BREAK_LOOP_OR_SWITCH_STMT_INFO,
					stStatementAccess.break_statement.get(i));
			break;
		case STMT_RETURN:
			sqlite3_bind_int(stmt, STMT_RETURN_EXP_INFO,
					stStatementAccess.return_exp.get(i));
			break;
		default:
			break;
		}

		sqlite3_bind_int(stmt, STMT_CODE_SCOPE_INFO,
				stStatementAccess.codeScp.get(i));

		parentKind = stStatementAccess.parentKind.get(i);
		sqlite3_bind_int(stmt, STMT_PARENT_KIND, parentKind);

		switch (parentKind) {
		case KIND_SYMDEFINFO:
			sqlite3_bind_int(stmt, STMT_PARENT_TABLE_INFO,
					stStatementAccess.parent_Symbol.get(i));
			break;
		case KIND_STATEMENTINFO:
			sqlite3_bind_int(stmt, STMT_PARENT_TABLE_INFO,
					stStatementAccess.parent_statement.get(i));
			break;
		case KIND_EXPRESSIONINFO:
			sqlite3_bind_int(stmt, STMT_PARENT_TABLE_INFO,
					stStatementAccess.parent_expression.get(i));
			break;
		default:
			sqlite3_bind_int(stmt, STMT_PARENT_TABLE_INFO, 0);
			break;
		}

		sqlite3_bind_int(stmt, STMT_BEFORE, stStatementAccess.before.get(i));
		sqlite3_bind_int(stmt, STMT_NEXT, stStatementAccess.next.get(i));
		sqlite3_bind_int(stmt, STMT_LIST_BEGINE,
				stStatementAccess.begin.get(i));
		sqlite3_bind_int(stmt, STMT_LIST_END, stStatementAccess.end.get(i));

		rc = sqlite3_step(stmt);
		if (rc != SQLITE_DONE) {
			bIsErr = TRUE;
			printf("%s", sqlite3_errmsg(db));
			break;
		}
		sqlite3_reset(stmt);
	}

	if (bIsErr) {
		rc = sqlite3_exec(db, "rollback;", 0, 0, 0);
	} else {
		rc = sqlite3_exec(db, "commit;", 0, 0, 0);
	}

	if (sql_insert != NULL ) {
		sqlite3_free(sql_insert);
	}
	if (stmt != NULL ) {
		rc = sqlite3_finalize(stmt);
	}
	return rc;
}

/*TBL_SYMBOLINFO*/
static INT insertSymbolInfo(sqlite3 *db, AST tuIdx) {
	INT rc = 0;
	sqlite3_stmt * stmt;
	const char *zTail;
	PSZ sql_insert = NULL;
	BOOL bIsErr = FALSE;

	AST max = 0;
	AST i = 0;

	rc = sqlite3_exec(db, "begin;", 0, 0, 0);
	if (rc != SQLITE_OK) {
		return rc;
	}

	max = stSymbolInfoAccess.getMax();

	sql_insert = sqlite3_mprintf(
			"INSERT INTO %q VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);",
			TBL_SYMBOLINFO);
	rc = sqlite3_prepare(db, sql_insert, -1, &stmt, &zTail);
	if (rc != SQLITE_OK || stmt == NULL ) {
		if (sql_insert != NULL ) {
			sqlite3_free(sql_insert);
		}
		if (stmt != NULL ) {
			sqlite3_finalize(stmt);
		}
		return COEXIT_ERROR;
	}

	for (i = 1; i <= max; i++) {

		sqlite3_bind_int(stmt, CC_UNIT_INDEX, tuIdx);
		sqlite3_bind_int(stmt, CC_TABLE_INDEX, i);

		sqlite3_bind_int(stmt, SYMBOL_CLASS,
				stSymbolInfoAccess.symClass.get(i));

		sqlite3_bind_int(stmt, SYMBOL_NAMESPACE,
				stSymbolInfoAccess.nameSpace.get(i));

		sqlite3_bind_int(stmt, SYMBOL_KIND, stSymbolInfoAccess.kind.get(i));

		sqlite3_bind_int(stmt, SYMBOL_TYPE_INFO,
				stSymbolInfoAccess.type.get(i));

		sqlite3_bind_int(stmt, SYMBOL_LINKAGE_INFO,
				stSymbolInfoAccess.linkage.get(i));

		sqlite3_bind_int(stmt, SYMBOL_IS_REFERRED,
				stSymbolInfoAccess.referred.get(i));

		sqlite3_bind_text(stmt, SYMBOL_NAME, stSymbolInfoAccess.name.get(i), -1,
				SQLITE_STATIC );

		sqlite3_bind_int(stmt, SYMBOL_CODE_SCOPE_INFO,
				stSymbolInfoAccess.codeScp.get(i));

		sqlite3_bind_int(stmt, SYMBOL_FUNCTION_BODY_STMT_INFO,
				stSymbolInfoAccess.functionBody.get(i));

		sqlite3_bind_int(stmt, SYMBOL_DATA_SECTION_INFO,
				stSymbolInfoAccess.dataSection.get(i));

		sqlite3_bind_int(stmt, SYMBOL_INIT_EXP_LIST_INFO,
				stSymbolInfoAccess.initialExpList.get(i));

		sqlite3_bind_int(stmt, SYMBOL_INIT_VALUE_INFO,
				stSymbolInfoAccess.value.get(i));

		sqlite3_bind_int(stmt, SYMBOL_MEMBER_OFFSET_BYTES,
				stSymbolInfoAccess.memOffset.get(i));

		rc = sqlite3_step(stmt);
		if (rc != SQLITE_DONE) {
			bIsErr = TRUE;
			printf("%s", sqlite3_errmsg(db));
			break;
		}
		sqlite3_reset(stmt);
	}

	if (bIsErr) {
		rc = sqlite3_exec(db, "rollback;", 0, 0, 0);
	} else {
		rc = sqlite3_exec(db, "commit;", 0, 0, 0);
	}

	if (sql_insert != NULL ) {
		sqlite3_free(sql_insert);
	}
	if (stmt != NULL ) {
		rc = sqlite3_finalize(stmt);
	}
	return rc;
}

/*TBL_LINKAGE*/
static INT insertLinkage(sqlite3 *db, AST tuIdx) {
	INT rc = 0;
	sqlite3_stmt * stmt;
	const char *zTail;
	PSZ sql_insert = NULL;
	BOOL bIsErr = FALSE;

	AST max = 0;
	AST i = 0;

	rc = sqlite3_exec(db, "begin;", 0, 0, 0);
	if (rc != SQLITE_OK) {
		return rc;
	}

	max = stCCLinkageAccess.getMax();

	sql_insert = sqlite3_mprintf("INSERT INTO %q VALUES(?,?,?,?,?,?,?,?);",
			TBL_LINKAGE);
	rc = sqlite3_prepare(db, sql_insert, -1, &stmt, &zTail);
	if (rc != SQLITE_OK || stmt == NULL ) {
		if (sql_insert != NULL ) {
			sqlite3_free(sql_insert);
		}
		if (stmt != NULL ) {
			sqlite3_finalize(stmt);
		}
		return COEXIT_ERROR;
	}

	for (i = 1; i <= max; i++) {

		sqlite3_bind_int(stmt, CC_UNIT_INDEX, tuIdx);
		sqlite3_bind_int(stmt, CC_TABLE_INDEX, i);

		sqlite3_bind_int(stmt, LINK_IS_EXTERNAL,
				stCCLinkageAccess.bExternal.get(i));

		sqlite3_bind_int(stmt, LINK_IS_REFERRED,
				stCCLinkageAccess.bReferred.get(i));

		sqlite3_bind_int(stmt, LINK_ALL_CHAIN_INFO,
				stCCLinkageAccess.allChain.get(i));

		sqlite3_bind_int(stmt, LINK_TEN_DECL_CHAIN_INFO,
				stCCLinkageAccess.tenDeclChain.get(i));

		sqlite3_bind_int(stmt, LINK_DEFINITION_CHAIN_INFO,
				stCCLinkageAccess.definitionChain.get(i));

		sqlite3_bind_int(stmt, LINK_DEF_SYMBOL_INFO,
				stCCLinkageAccess.definitionSym.get(i));

		rc = sqlite3_step(stmt);
		if (rc != SQLITE_DONE) {
			bIsErr = TRUE;
			printf("%s", sqlite3_errmsg(db));
			break;
		}
		sqlite3_reset(stmt);
	}

	if (bIsErr) {
		rc = sqlite3_exec(db, "rollback;", 0, 0, 0);
	} else {
		rc = sqlite3_exec(db, "commit;", 0, 0, 0);
	}

	if (sql_insert != NULL ) {
		sqlite3_free(sql_insert);
	}
	if (stmt != NULL ) {
		rc = sqlite3_finalize(stmt);
	}
	return rc;
}

/*TBL_TYPEINFO*/
static INT insertTypeInfo(sqlite3 *db, AST tuIdx) {
	INT rc = 0;
	sqlite3_stmt * stmt;
	const char *zTail;
	PSZ sql_insert = NULL;
	BOOL bIsErr = FALSE;

	AST max = 0;
	AST i = 0;

	rc = sqlite3_exec(db, "begin;", 0, 0, 0);
	if (rc != SQLITE_OK) {
		return rc;
	}

	max = stTypeInfoAccess.getMax();

	sql_insert = sqlite3_mprintf(
			"INSERT INTO %q VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);",
			TBL_TYPEINFO);
	rc = sqlite3_prepare(db, sql_insert, -1, &stmt, &zTail);
	if (rc != SQLITE_OK || stmt == NULL ) {
		if (sql_insert != NULL ) {
			sqlite3_free(sql_insert);
		}
		if (stmt != NULL ) {
			sqlite3_finalize(stmt);
		}
		return COEXIT_ERROR;
	}

	for (i = 1; i <= max; i++) {
		sqlite3_bind_int(stmt, CC_UNIT_INDEX, tuIdx);
		sqlite3_bind_int(stmt, CC_TABLE_INDEX, i);

		sqlite3_bind_int(stmt, TYPE_KIND, stTypeInfoAccess.typeKind.get(i));

		sqlite3_bind_int(stmt, TYPE_SIGN, stTypeInfoAccess.signFlag.get(i));

		sqlite3_bind_int(stmt, TYPE_LENGTH,
				stTypeInfoAccess.longShortFlg.get(i));

		sqlite3_bind_int(stmt, TYPE_FLOATING, stTypeInfoAccess.intFloat.get(i));

		sqlite3_bind_int(stmt, TYPE_EQUAL, stTypeInfoAccess.typeQual.get(i));

		sqlite3_bind_int(stmt, TYPE_SIZE, stTypeInfoAccess.size.get(i));

		sqlite3_bind_int(stmt, TYPE_ELEMENT_TYPE_INFO,
				stTypeInfoAccess.elementType.get(i));

		sqlite3_bind_int(stmt, TYPE_NONE_QUALIFIER_TYPE_INFO,
				stTypeInfoAccess.noQualType.get(i));

		sqlite3_bind_int(stmt, TYPE_MEMBER_CHAIN_INFO,
				stTypeInfoAccess.memChain.get(i));

		sqlite3_bind_int(stmt, TYPE_TAG_SYMBOL_INFO,
				stTypeInfoAccess.tagInfo.get(i));

		sqlite3_bind_int(stmt, TYPE_NEXT, stTypeInfoAccess.next.get(i));

		sqlite3_bind_int(stmt, TYPE_UNDEF_FLAG,
				stTypeInfoAccess.bSizeUnDefined.get(i));

		sqlite3_bind_int(stmt, TYPE_VSIZE_FLAG,
				stTypeInfoAccess.bVariableSize.get(i));

		rc = sqlite3_step(stmt);
		if (rc != SQLITE_DONE) {
			bIsErr = TRUE;
			printf("%s", sqlite3_errmsg(db));
			break;
		}
		sqlite3_reset(stmt);
	}

	if (bIsErr) {
		rc = sqlite3_exec(db, "rollback;", 0, 0, 0);
	} else {
		rc = sqlite3_exec(db, "commit;", 0, 0, 0);
	}

	if (sql_insert != NULL ) {
		sqlite3_free(sql_insert);
	}
	if (stmt != NULL ) {
		rc = sqlite3_finalize(stmt);
	}
	return rc;
}

/*TBL_VALUEINFO*/
static INT insertValueInfo(sqlite3 *db, AST tuIdx) {
	INT rc = 0;
	sqlite3_stmt * stmt;
	const char *zTail;
	PSZ sql_insert = NULL;
	BOOL bIsErr = FALSE;

	AST max = 0;
	AST i = 0;
	AST typeKind = 0;

	rc = sqlite3_exec(db, "begin;", 0, 0, 0);
	if (rc != SQLITE_OK) {
		return rc;
	}

	max = stValueInfoAccess.getMax();

	sql_insert = sqlite3_mprintf("INSERT INTO %q VALUES(?,?,?,?,?);",
			TBL_VALUEINFO);
	rc = sqlite3_prepare(db, sql_insert, -1, &stmt, &zTail);
	if (rc != SQLITE_OK || stmt == NULL ) {
		if (sql_insert != NULL ) {
			sqlite3_free(sql_insert);
		}
		if (stmt != NULL ) {
			sqlite3_finalize(stmt);
		}
		return COEXIT_ERROR;
	}

	for (i = 1; i <= max; i++) {
		sqlite3_bind_int(stmt, CC_UNIT_INDEX, tuIdx);
		sqlite3_bind_int(stmt, CC_TABLE_INDEX, i);

		typeKind = stValueInfoAccess.type.get(i);
		sqlite3_bind_int(stmt, VALUE_TYPE_INFO, typeKind);

		sqlite3_bind_int(stmt, VALUE_INTEGER_VALUE, 0);
		sqlite3_bind_double(stmt, VALUE_FLOATING_VALUE, 0);
		switch (typeKind) {
		case TYPE_CHAR:
		case TYPE_SIGNED_CHAR:
		case TYPE_UNSIGNED_CHAR:
		case TYPE_SHORT:
		case TYPE_SIGNED_SHORT:
		case TYPE_UNSIGNED_SHORT:
		case TYPE_INT:
		case TYPE_SIGNED_INT:
			sqlite3_bind_int(stmt, VALUE_INTEGER_VALUE,
					stValueInfoAccess.s4value.get(i));
			break;
		case TYPE_UNSIGNED_INT:
			sqlite3_bind_int(stmt, VALUE_INTEGER_VALUE,
					stValueInfoAccess.u4value.get(i));
			break;
		case TYPE_LONG:
		case TYPE_SIGNED_LONG:
		case TYPE_LONG_LONG:
		case TYPE_SIGNED_LONG_LONG:
			sqlite3_bind_int(stmt, VALUE_INTEGER_VALUE,
					stValueInfoAccess.s8value.get(i));
			break;
		case TYPE_UNSIGNED_LONG:
		case TYPE_UNSIGNED_LONG_LONG:
			sqlite3_bind_int(stmt, VALUE_INTEGER_VALUE,
					stValueInfoAccess.u8value.get(i));
			break;
		case TYPE_FLOAT:
		case TYPE_DOUBLE:
		case TYPE_LONG_DOUBLE:
			sqlite3_bind_double(stmt, VALUE_FLOATING_VALUE,
					stValueInfoAccess.dvalue.get(i));
			break;
		default:
			break;
		}

		rc = sqlite3_step(stmt);
		if (rc != SQLITE_DONE) {
			bIsErr = TRUE;
			printf("%s", sqlite3_errmsg(db));
			break;
		}
		sqlite3_reset(stmt);
	}

	if (bIsErr) {
		rc = sqlite3_exec(db, "rollback;", 0, 0, 0);
	} else {
		rc = sqlite3_exec(db, "commit;", 0, 0, 0);
	}

	if (sql_insert != NULL ) {
		sqlite3_free(sql_insert);
	}
	if (stmt != NULL ) {
		rc = sqlite3_finalize(stmt);
	}
	return rc;
}

/*TBL_UNITECHAIN*/
static INT insertUniteChain(sqlite3 *db, AST tuIdx) {
	INT rc = 0;
	sqlite3_stmt * stmt;
	const char *zTail;
	PSZ sql_insert = NULL;
	BOOL bIsErr = FALSE;

	AST max = 0;
	AST i = 0;
	U2 chainKind = 0;

	rc = sqlite3_exec(db, "begin;", 0, 0, 0);
	if (rc != SQLITE_OK) {
		return rc;
	}

	max = stUniteChainAccess.getMax();

	sql_insert = sqlite3_mprintf("INSERT INTO %q VALUES(?,?,?,?,?,?);",
			TBL_UNITECHAIN);
	rc = sqlite3_prepare(db, sql_insert, -1, &stmt, &zTail);
	if (rc != SQLITE_OK || stmt == NULL ) {
		if (sql_insert != NULL ) {
			sqlite3_free(sql_insert);
		}
		if (stmt != NULL ) {
			sqlite3_finalize(stmt);
		}
		return COEXIT_ERROR;
	}

	for (i = 1; i <= max; i++) {
		sqlite3_bind_int(stmt, CC_UNIT_INDEX, tuIdx);
		sqlite3_bind_int(stmt, CC_TABLE_INDEX, i);

		chainKind = stUniteChainAccess.kind.get(i);
		sqlite3_bind_int(stmt, CHAIN_KIND, chainKind);

		switch (chainKind) {
		case KIND_SYMDEFINFO:
			sqlite3_bind_int(stmt, CHAIN_TABLE_INFO,
					stUniteChainAccess.parameter_sym.get(i));
			break;
		case KIND_STATEMENTINFO:
			sqlite3_bind_int(stmt, CHAIN_TABLE_INFO,
					stUniteChainAccess.parameter_stmt.get(i));
			break;
		case KIND_DECLARATION:
			sqlite3_bind_int(stmt, CHAIN_TABLE_INFO,
					stUniteChainAccess.parameter_decl.get(i));
			break;
		default:
			sqlite3_bind_int(stmt, CHAIN_TABLE_INFO, 0);
			break;
		}

		sqlite3_bind_int(stmt, CHAIN_PRE_CHAIN_INFO,
				stUniteChainAccess.before.get(i));

		sqlite3_bind_int(stmt, CHAIN_NEXT_CHAIN_INFO,
				stUniteChainAccess.next.get(i));

		rc = sqlite3_step(stmt);
		if (rc != SQLITE_DONE) {
			bIsErr = TRUE;
			printf("%s", sqlite3_errmsg(db));
			break;
		}
		sqlite3_reset(stmt);
	}

	if (bIsErr) {
		rc = sqlite3_exec(db, "rollback;", 0, 0, 0);
	} else {
		rc = sqlite3_exec(db, "commit;", 0, 0, 0);
	}

	if (sql_insert != NULL ) {
		sqlite3_free(sql_insert);
	}
	if (stmt != NULL ) {
		rc = sqlite3_finalize(stmt);
	}
	return rc;
}

/*insert cc tables*/
INT DLL_EXPORT insertCcTables(sqlite3 *db, AST tuIdx) {
	INT rc = 0;

	rc = insertDeclaration(db, tuIdx);
	if (rc != COEXIT_SUCCESS) {
		return rc;
	}

	rc = insertDeclarator(db, tuIdx);
	if (rc != COEXIT_SUCCESS) {
		return rc;
	}

	rc = insertTypeSpecifier(db, tuIdx);
	if (rc != COEXIT_SUCCESS) {
		return rc;
	}

	rc = insertExpression(db, tuIdx);
	if (rc != COEXIT_SUCCESS) {
		return rc;
	}

	rc = insertExpressionList(db, tuIdx);
	if (rc != COEXIT_SUCCESS) {
		return rc;
	}

	rc = insertInitializerDesignation(db, tuIdx);
	if (rc != COEXIT_SUCCESS) {
		return rc;
	}

	rc = insertStatement(db, tuIdx);
	if (rc != COEXIT_SUCCESS) {
		return rc;
	}

	rc = insertSymbolInfo(db, tuIdx);
	if (rc != COEXIT_SUCCESS) {
		return rc;
	}

	rc = insertLinkage(db, tuIdx);
	if (rc != COEXIT_SUCCESS) {
		return rc;
	}

	rc = insertTypeInfo(db, tuIdx);
	if (rc != COEXIT_SUCCESS) {
		return rc;
	}

	rc = insertValueInfo(db, tuIdx);
	if (rc != COEXIT_SUCCESS) {
		return rc;
	}

	rc = insertUniteChain(db, tuIdx);
	if (rc != COEXIT_SUCCESS) {
		return rc;
	}

	return COEXIT_SUCCESS;
}
